import { CreateNode } from "./CreateNode";
import { Main } from "./Main";
import { Hexagonal, OnType } from "./Hexagonal";
import { Map } from "./Map";
import { MoveHexa } from "./MoveHexa";


const hoxa_list = [2,4,8,16,32,64,128,256,512,1024];

/** 游戏玩法控制模块 处理游戏玩法，控制 游戏输赢*/
export  class GameControl{

    /** 地图节点 */
    public mapNode:cc.Node = null;

    /** 生成的六边形父节点 */
    private _Hexagonal_parent:cc.Node = null;

    /** 移动六边形模块 */
    public _Hexagonal:Hexagonal = null;

    /** 地图控制模块 */
    public Mapcontrol:Map = null;

    /** 生成六边形的位置 */
    private _hexaPosition:cc.Vec2 = cc.v2(0,-700);

    /** 界面所有位置节点 ，对应所有地图六边形蜂巢节点 */
    public _hexagonal_List:Array<cc.Node> = new Array();

    public _canPlaceList:Array<number> = [];

    /** 点击移动的六边形节点 */
    public _moveNode:cc.Node = null;
    public _anotherNode:cc.Node = null;
   
    /** 可以放置的位置编号 */
    private _PlaceIndex:number = 0;
    /** 点击放置的六边形等级 */
    private _PlaceLevel:number = 0;

    /** 是否已经进行第二个消除 */
    public _iseliminate:boolean = false;

    set PlaceLevel(lev){
        this._PlaceLevel = lev;
    }

    public _onType:OnType = null;
    private _oneCount:boolean = true;

    /** 是否可以进行点击 */
    public _cantouch:boolean = true;
    
    constructor(node:cc.Node,map:Map){
        
        this.mapNode = node;
        this.Mapcontrol = map;
        this._Hexagonal_parent = new CreateNode("Hexagonal_parent");
    }

    public init(){

        // let h_spr = this._Hexagonal_parent.addComponent(cc.Sprite);
        let spr = cc.loader.getRes("main/cirlceChange",cc.SpriteFrame);
        this._Hexagonal_parent.setContentSize(spr.getOriginalSize().width,spr.getOriginalSize().height);
        this._Hexagonal_parent.zIndex = 200;
        this.mapNode.addChild(this._Hexagonal_parent);
        this._Hexagonal_parent.setPosition(this._hexaPosition);
        this._Hexagonal =  this._Hexagonal_parent.addComponent(Hexagonal);  
        this._hexagonal_List = Main.Map._hexagonal_List;
        this.addMoveHexagonal([1,1]);
        this._onType = OnType.IDLE;
    }

    /**
     * 添加一个可移动的六边形  控制生成的类型概率  以及形状
     * @param useshape 可生成的六边形类型列表 
     * 形状  0 为单个  1为两个，上方元素在左上角   2为上方元素在右上角  3为横向
     */
    public addMoveHexagonal (useshape:Array<number>){

        let Level = Main.AllData.Level;
        let shape = 0;
        let level_List = [];
        let sharand = Math.random();
        if(sharand > 0.2){
            if(useshape.length == 1){
                shape = 0;
                level_List.push(hoxa_list[Math.floor(Math.random() * hoxa_list.indexOf(Level))]); 
            }else{
                //随机选择一个类型
                let shapeList = [1,2,3];
                shape = shapeList[Math.floor(Math.random() * shapeList.length)];
                for(let i=0;i<useshape.length;i++){
                    level_List.push(hoxa_list[Math.floor(Math.random() * hoxa_list.indexOf(Level))]);
                }
            }            
        }else{
            //只能生成单个
            shape = 0;
            level_List.push(hoxa_list[Math.floor(Math.random() * hoxa_list.indexOf(Level))]);
        }

        this._Hexagonal.addMoveHexagonal(level_List,shape,this.MoveHexagonal,this.EndHexagonalMove);
    }


    public MoveHexagonal (touch){

        cc.log("移动");
        
        if(!this._cantouch){
            return;
        }
        if(this._oneCount){
            this._oneCount = false;
            this._onType = OnType.MOVE;
        }
        let pos;
        let Re_hone;
        pos = this._Hexagonal.node.convertTouchToNodeSpaceAR(touch);
        Re_hone = this.mapNode.convertToNodeSpaceAR(touch.getLocation());
        this.isEnterhoneycomb(this.setTargetPos(touch.target,pos,Re_hone));
    }

    /**
     * 设置类型为双元素可移动六边形的位置   返回在移动列表中的位置和位置点击元素在列表中的id
     * @param onNode 点击的移动六边形节点
     * @param pos 需要移动到的位置
     * @param re_hone 相对以蜂巢的位置
     */
    public setTargetPos(onNode:cc.Node,endpos:cc.Vec2,re_hone:cc.Vec2) {
        let type = this._Hexagonal.getHexagonal_type();
        let Hexagonal_list = this._Hexagonal.MoveHexagonal_List;
        let pos = [];
        let id = 0;
        for(let i=0;i<Hexagonal_list.length;i++){
            if(Hexagonal_list[i] == onNode){
                onNode.setPosition(endpos);
                pos.push(re_hone);
                id = i;
            }else{
                //计算相对距离   0 表示左边   1表示右边
                let repos = this._Hexagonal.CalculateDistance(i+1,type);
                Hexagonal_list[i].setPosition(endpos.x + repos.x,endpos.y + repos.y);
                pos.push(cc.v2(re_hone.x + repos.x,re_hone.y + repos.y));
            }
                  
        }
        return {pos,id};

    }

    /**
     * 结束放置
     * @param touch 
     */
    public EndHexagonalMove(touch){

        cc.log("结束",touch.type);
        this._oneCount = true;
        this._moveNode = touch.target;
        let Hexagonal_list = this._Hexagonal.MoveHexagonal_List;
        if(Hexagonal_list.length > 1){
            for(let i=0;i<Hexagonal_list.length;i++){
                if(this._moveNode.name != Hexagonal_list[i].name){
                    this._anotherNode = Hexagonal_list[i];
                }
            }
        }else{
            this._anotherNode = null;    
        }       
        let pos = this._Hexagonal.node.convertTouchToNodeSpaceAR(touch);
        let Re_hone = this.mapNode.convertToNodeSpaceAR(touch.getLocation());
        let data =  this.isEnterhoneycomb(this.setTargetPos(touch.target,pos,Re_hone));
        this.placehoneycomb(data);
        setTimeout(()=>{
            this._onType = OnType.IDLE;
        },0)

    }

    /**
     * 判断是否进入蜂巢 如果进入了就显示提示
     * @param posdata 保存的正在移动的六边形相对于蜂巢的位置
     */
    public isEnterhoneycomb (posdata:any){
        let arr:Array<number> = [];
        let data_1 = {
            canplace:false,
            poslist:arr,
            id:posdata.id,
        }
        let type = this._Hexagonal.getHexagonal_type();
        //单个元素
        if(posdata.pos.length == 1){
            for(let i=0;i<this._hexagonal_List.length;i++){
                let rect = this._hexagonal_List[i].getBoundingBox();
                if(cc.rectContainsPoint(rect,posdata.pos[0])){
                    //判断该位置是否有元素
                    let canplace:boolean = Main.AllData.canPlace(i);
                    if(!canplace){
                        data_1.canplace = true;
                        data_1.poslist.push(i);
                        this.Mapcontrol.ShowLighten([this._hexagonal_List[i]]);
                    }        
                    break;
                }else{
                    this.Mapcontrol.HideLighten(); 
                    
                }   
                
            }
            return data_1;  
        }else if(posdata.pos.length == 2){
            
            let data_2 = {
                canplace:false,
                id:0,
            }
            for(let i=0;i<this._hexagonal_List.length;i++){
                let rect = this._hexagonal_List[i].getBoundingBox();
                if(cc.rectContainsPoint(rect,posdata.pos[0])){
                    //判断该位置是否有元素
                    let canplace:boolean = Main.AllData.canPlace(i);
                    if(!canplace){
                        data_1.canplace = true;
                        data_1.poslist.push(i);
                    }  
                }  
                if(cc.rectContainsPoint(rect,posdata.pos[1])){
                    //判断该位置是否有元素
                    let canplace:boolean = Main.AllData.canPlace(i);
                    if(!canplace){
                        data_2.canplace = true;
                        data_2.id = i;
                    }        
                }   
            }  
            if(data_1.poslist.length == 0){
                data_1.poslist.push(0);
            }
            let postype = Main.AllData.deteType([data_1.poslist[0],data_2.id]);
            if(data_1.canplace && data_2.canplace && postype == type){

                this.Mapcontrol.ShowLighten([this._hexagonal_List[data_1.poslist[0]],this._hexagonal_List[data_2.id]]);
                return {canplace:data_1.canplace,poslist:[data_1.poslist[0],data_2.id],id:posdata.id};
            }else{
                this.Mapcontrol.HideLighten();   
                return {canplace:false,poslist:[data_1.poslist[0],data_2.id],id:posdata.id};
            }
        }
        

    }

    /** 将六边形放置在蜂巢中 */
    public placehoneycomb (data:any){

        this.Mapcontrol.HideLighten(); 
        if(data.canplace){
            
            this._canPlaceList = data.poslist;
            let completecall = Main.CountCallback(data.poslist.length,()=>{
                this._Hexagonal.removeHexagonalOn();
            })
            for(let i=0;i<data.poslist.length;i++){
                this._Hexagonal.addHexagonalToMap(i,data.poslist[i],completecall);
            }
            this._iseliminate = false;
            this._PlaceIndex = this._canPlaceList.shift();
            this.DetectCanbeEliminated(0);
        }else{
            this._Hexagonal.comeback();
        }
       
    }

    public anotherEliminated (){

        cc.log("第二个元素消除");
        this._iseliminate = true;
        if(this._anotherNode){
            cc.log("另一个元素消除");
            let moveHexa:MoveHexa = this._anotherNode.getComponent(MoveHexa);
            this._PlaceIndex = moveHexa.locationPos;
            this._PlaceLevel = moveHexa.Level;
            cc.log(this._anotherNode);
            this.DetectCanbeEliminated(0);
        }else{
            cc.log("直接进行一下步");
            this.DetectCanbeEliminated(0);
        }
    }

    /** 检测是否可以消除 */
    public DetectCanbeEliminated (index:number){

        let compltecall = ()=>{
            index++;   
            this.DetectCanbeEliminated(index);          
        }
      
        let data:Array<number> = Main.AllData.ConvertNumberingTodata(this._PlaceIndex);
        let canEliminate = Main.AllData.CalculatesAll(data);
        cc.log("可消除==>",canEliminate,this._PlaceIndex);
        if(canEliminate.length >= 3 && !index){
            //执行第一轮消除动画
            this.Mapcontrol.EliminateAnimation(this._PlaceIndex,canEliminate,compltecall);
        }else if(canEliminate.length >= 2 && index){
            //执行第二波消除
            this.Mapcontrol.EliminateAnimation(this._PlaceIndex,canEliminate,compltecall);
        }else{

            if(this._canPlaceList.length == 0){

                let usedata = Main.AllData.isGameOver();
                if(!usedata.havepos){
                    cc.log("游戏结束");
                }else{
                    cc.log("可使用数据==>",usedata);
                    this._cantouch = true;
                    this.addMoveHexagonal([2,2]);
                }
            }else{
                this._PlaceIndex = this._canPlaceList.shift();
                this.DetectCanbeEliminated(0);
            }         
        }
        
    }
 
}